package cn.com.okgo.convert;

import android.text.TextUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import cn.com.okgo.callback.HttpCallback;
import cn.com.okgo.utils.Exceptions;
import cn.com.okgo.utils.ThreadUtils;
import okhttp3.Response;

public class FileConvert implements Converter<File> {

    private String destFileDir;     //目标文件存储的文件夹路径
    private String destFileName;    //目标文件存储的文件名
    private String destFileNameTmp;//目标文件存储的临时文件
    private HttpCallback callback;  //下载回调

    public FileConvert(String destFileDir, String destFileName) {
        this.destFileDir = destFileDir;
        this.destFileName = destFileName;
        this.destFileNameTmp=destFileName+".tmp";
    }

    public void setCallback(HttpCallback callback) {
        this.callback = callback;
    }

    @Override
    public File convertSuccess(Response value) throws Exception {

        if (TextUtils.isEmpty(destFileDir) || TextUtils.isEmpty(destFileNameTmp)) {
            Exceptions.illegalArgument("destFileDir or destFileName can not be null.");
        }

        File dir = new File(destFileDir);
        if (!dir.exists()) dir.mkdirs();
        File file = new File(dir, destFileName);
        if (file.exists()) file.delete();
        File fileTmp = new File(dir, destFileNameTmp);
        if (fileTmp.exists()) fileTmp.delete();

        long lastRefreshUiTime = 0;  //最后一次刷新的时间
        long lastWriteBytes = 0;     //最后一次写入字节数据

        InputStream is = null;
        byte[] buf = new byte[2048];
        FileOutputStream fos = null;
        try {
            is = value.body().byteStream();
            final long total = value.body().contentLength();
            long sum = 0;
            int len;
            fos = new FileOutputStream(fileTmp);
            while ((len = is.read(buf)) != -1) {
                sum += len;
                fos.write(buf, 0, len);

                //下载进度回调
                if (callback != null) {
                    final long finalSum = sum;
                    long curTime = System.currentTimeMillis();
                    //每200毫秒刷新一次数据
                    if (curTime - lastRefreshUiTime >= 100 || finalSum == total) {
                        //计算下载速度
                        long diffTime = (curTime - lastRefreshUiTime) / 1000;
                        if (diffTime == 0) diffTime += 1;
                        final long diffBytes = finalSum - lastWriteBytes;
                        final long networkSpeed = diffBytes / diffTime;
                        ThreadUtils.dispatchToMainThread(new Runnable() {
                            @Override
                            public void run() {
                                if(total < 0){
                                    callback.onDownloadProgressByte(networkSpeed, finalSum);
                                }else{
                                    callback.onDownloadProgress(finalSum * 1.0f / total, total);
                                }

                            }
                        });

                        lastRefreshUiTime = System.currentTimeMillis();
                        lastWriteBytes = finalSum;
                    }
                }
            }
            fos.flush();
            fileTmp.renameTo(file);
            return file;
        }  finally {
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) fos.close();
            } catch (IOException e) {
                 e.printStackTrace();
            }
        }
    }
}